package com.foreveross.bsl.common.utils.balance.zookeeper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

import java.util.Map;

/**
 * Property Manager. 配置中心
 * <p/>
 * You can add/update/remove a property.
 * 
 * @author heyaowen Date: 2010-9-30 15:27:04
 */
public class PropertyCenter {

	private static final Log log = LogFactory.getLog(PropertyCenter.class);

	private ZooKeeper zk;
	private String charset = "UTF-8";
	private String root = "";

	public void setZooKeeper(ZooKeeper zk) {
		this.zk = zk;
	}

	public void setCharset(String charset) {
		this.charset = charset;
	}

	public void setRoot(String root) {
		if (root != null && root.length() > 0) {
			if (!root.startsWith("/")) {
				root = "/" + root;
			}

			this.root = root;
		}
	}

	public boolean createRootNode(String node) {
		assert node != null;

		if (!node.startsWith("/")) {
			node = "/" + node;
		}

		try {
			Stat s = zk.exists(node, false);

			if (s == null) {
				zk.create(node, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
						CreateMode.PERSISTENT);
			}
		} catch (Exception e) {
			log.error("update property error: " + node, e);
			return false;
		}
		return true;
	}

	protected String buildName(String name) {
		return root + "/" + name;
	}

	public String getStringProperty(String name) {
		try {
			byte[] data = zk.getData(buildName(name), false, null);
			return new String(data, charset);
		} catch (Exception e) {
			log.error("read property error: " + name, e);
			return null;
		}
	}

	public byte[] getProperty(String name) {
		try {
			return zk.getData(buildName(name), false, null);
		} catch (Exception e) {
			log.error("read property error: " + name, e);
			return null;
		}
	}

	public boolean updateProperty(String name, String data) {
		try {
			return updateProperty(name, data.getBytes(charset));
		} catch (Exception e) {
			log.error("update property error: " + name, e);
			return false;
		}
	}

	public boolean updateProperty(String name, byte[] data) {
		try {
			Stat s = zk.exists(buildName(name), false);

			if (s == null) {
				zk.create(buildName(name), data, ZooDefs.Ids.OPEN_ACL_UNSAFE,
						CreateMode.PERSISTENT);
			} else {
				zk.setData(buildName(name), data, -1);
			}
		} catch (Exception e) {
			log.error("update property error: " + name, e);
			return false;
		}

		return true;
	}

	public boolean deleteProperty(String name) {
		try {
			Stat s = zk.exists(buildName(name), false);

			if (s != null) {
				zk.delete(buildName(name), -1);
			}
		} catch (Exception e) {
			log.error("delete property error: " + name, e);
			return false;
		}

		return true;
	}

	public Map<String, String> getStringGroupProperties(String name) {
		// todo

		return null;
	}

	public Map<String, byte[]> getGroupProperties(String name) {
		// todo

		return null;
	}

}
